﻿#include "DAPluginManager.h"
#include <QDir>
#include <QDebug>
#include <QCoreApplication>
#include "DAPluginOption.h"
class DAPluginManagerPrivate
{
    DA_IMPL_PUBLIC(DAPluginManager)
public:
    DAPluginManagerPrivate(DAPluginManager *p);

    QDir _pluginDir;
    QString _suffix; ///< 插件的后缀
    QList<DAPluginOption> _pluginOptions;
    bool _isLoaded; ///< 标记是否加载了，可以只加载一次
};

DAPluginManagerPrivate::DAPluginManagerPrivate(DAPluginManager *p)
    : q_ptr(p)
#if defined(Q_OS_WIN)
    , _suffix("dll")
#elif defined(Q_OS_UNIX)
    , _suffix("so")
#endif
    , _isLoaded(false)
{
    _pluginDir.setPath(QCoreApplication::applicationDirPath() + QDir::separator() + "plugins");
}

DAPluginManager::DAPluginManager(QObject *p) : QObject(p), d_ptr(new DAPluginManagerPrivate(this)) {}

DAPluginManager &DAPluginManager::instance()
{
    static DAPluginManager s_plugin_mgr;

    return (s_plugin_mgr);
}

/**
 * @brief FCPluginManager::setIgnoreList
 * @param ignorePluginsName
 */
void DAPluginManager::setIgnoreList(const QStringList ignorePluginsName) {}

/**
 * @brief 加载插件
 */
void DAPluginManager::load()
{
    QFileInfoList fileInfos = d_ptr->_pluginDir.entryInfoList(QDir::Files);

    qInfo() << tr("plugin dir is:") << d_ptr->_pluginDir.absolutePath();
    for (const QFileInfo &fi : fileInfos) {
        qDebug() << tr("start load plugin:") << fi.absoluteFilePath();
        if (fi.suffix().toLower() != d_ptr->_suffix.toLower()) {
            qDebug() << tr(" ignore invalid suffix:") << fi.suffix().toLower() << tr(" file is:") << fi.absoluteFilePath();
            continue;
        }
        DAPluginOption pluginopt;
        if (!pluginopt.load(fi.absoluteFilePath())) {
            qDebug() << tr("can not load plugin:") << fi.absoluteFilePath();
            continue;
        }
        d_ptr->_pluginOptions.append(pluginopt);
    }
    d_ptr->_isLoaded = true;
}

bool DAPluginManager::isLoaded() const
{
    return (d_ptr->_isLoaded);
}

/**
 * @brief 设置插件路径，可以多次load，同一个插件（插件名称和类型组成一个key）只会加载一次
 */
void DAPluginManager::setPluginPath(const QString &path)
{
    d_ptr->_pluginDir.setPath(path);
}

/**
 * @brief 获取加载成功插件的数量
 * @return
 */
int DAPluginManager::getPluginCount() const
{
    return (d_ptr->_pluginOptions.size());
}

/**
 * @brief 获取加载成功插件的插件名
 * @return
 */
QList<QString> DAPluginManager::getPluginNames() const
{
    QList<QString> res;

    for (const DAPluginOption &opt : d_ptr->_pluginOptions) {
        res.append(opt.getPluginName());
    }
    return (res);
}

/**
 * @brief 获取所有插件信息
 * @return
 */
QList<DAPluginOption> DAPluginManager::getPluginOptions() const
{
    return (d_ptr->_pluginOptions);
}

QDebug operator<<(QDebug debug, const DAPluginManager &fmg)
{
    QDebugStateSaver saver(debug);

    debug.nospace() << DAPluginManager::tr("Plugin Manager Info -> is loaded:") << fmg.isLoaded()
                    << DAPluginManager::tr(",plugin counts:") << fmg.getPluginCount() << endl;
    QList<DAPluginOption> opts = fmg.getPluginOptions();

    for (const DAPluginOption &opt : opts) {
        debug.nospace() << opt;
    }
    return (debug);
}
